// 

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int a;
    a = 6;
    // sizeof(): 变量或类型在内存中所占的字节数
    printf("sizeof(a) = %ld\n", sizeof(a));
    printf("sizeof(int) = %ld\n", sizeof(int));
    printf("sizeof(double) = %ld\n", sizeof(double));
    // sizeof(a) = 4
    // sizeof(int) = 4
    // sizeof(double) = 8

    // &: 获取变量的地址，它的操作数必须是变量
    // %x: 对应 int 类型，会以16进制形式输出
    // %p: 以地址形式输出
    // 地址与整数形式输出并不一定相同，与32位或64位架构也有关系
    printf("0x%x\n", &a);
    printf("%p\n", &a);
    int p = (int)&a;
    printf("%x\n", p);
    printf("%p\n", p);
    // 结果为：
    // 0x61fe18
    // 000000000061FE18
    // 61fe18
    // 000000000061FE18

    // &只能对变量取地址，不能取表达式的地址
    // &(i++)会报错

    // 相邻的变量在内存中的地址也是相邻的
    // C语言的变量以堆栈存储，分配时是*自顶向下的（高地址到低地址
    // 也就是栈底到栈顶，栈底是高地址
    int b, c;
    printf("\n%p\n%p\n%p\n%p", &a, p, &b, &c);
    // 结果为：
    // 000000000061FE18
    // 000000000061FE18
    // 000000000061FE14
    // 000000000061FE10

    // 相邻的数组单元的地址是相邻的
    // &a = &a[0]
    int array[] = {1, 2, 3};
    printf("\n\n%p\n%p\n%p\n", &array[0], &array[1], &array[2]);
    // 输出为：
    // 000000000061FE04
    // 000000000061FE08
    // 000000000061FE0C
    
    return 0;
}